package com.safone.thirdattendanceservices.common.services.impl;

import com.alibaba.fastjson.JSONObject;
import com.safone.thirdattendancecores.common.dtos.PersonQueryDto;
import com.safone.thirdattendanceservices.common.services.CommonService;
import com.safone.thirdattendanceservices.configs.ArgsUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;


/**
 * @author xy
 * @date 2020/12/4 20:47
 */
@Service
@Slf4j
@AllArgsConstructor
public class CommonServiceImpl implements CommonService{

    private RestTemplate restTemplate;

    private ArgsUtil argsUtil;

    @Override
    public String getRandomPublicKey() {
        String apiUrl = "/eags/security/getRandomPublicKey";
        String httpMethod = "GET";
        argsUtil.restTemplateExchange(apiUrl,httpMethod,null);

        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(null, argsUtil.getHeaders());
        //远程调用
        ResponseEntity<String> responseEntity = restTemplate.exchange(argsUtil.getDaHuaConfig().getUrl()+apiUrl, HttpMethod.GET, formEntity, String.class);
        JSONObject data = JSONObject.parseObject(responseEntity.getBody()).getJSONObject("data");
        String publicKey = data.get("publicKey").toString();
        return publicKey;
    }

    @Override
    public  Map<String,String> getMq() {
        //构造body
        String publicKey = getRandomPublicKey();
        Map hashMap = new HashMap(2);
        String key="123456789qwertyuiop";
        try {
            String secretKey = encrypt(key,publicKey);
            hashMap.put("secretKey",secretKey);
            log.info("加密密钥："+secretKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        hashMap.put("publicKey",publicKey);
        log.info("公钥："+publicKey);

        String apiUrl2 = "/eags/api/mq/v1.0";
        String httpMethod1 = "POST";
        String contentType ="application/json";
        argsUtil.restTemplateExchange(apiUrl2,httpMethod1,contentType);

        HttpHeaders headers = argsUtil.getHeaders();

        HttpEntity<Map<String, String>> formEntity = new HttpEntity<>(hashMap, headers);
        log.info("时间："+formEntity.getHeaders().get("X-LC-Date"));
        log.info("随机码："+formEntity.getHeaders().get("X-LC-Nonce"));
        log.info("Authorization："+formEntity.getHeaders().get("Authorization"));
        log.info("访问地址："+argsUtil.getDaHuaConfig().getUrl()+apiUrl2);
        ResponseEntity<Map> responseEntity = restTemplate.exchange(argsUtil.getDaHuaConfig().getUrl()+apiUrl2, HttpMethod.POST, formEntity, Map.class);
        log.info("mq登录信息："+responseEntity);
        Map<String,String> data = (Map<String,String>)responseEntity.getBody().get("data");

        String username = data.get("userName");
        String password = data.get("password");
        String userName = AesDecode(username, key);
        String passWord = AesDecode(password, key);
        Map<String, String> mqMap = new HashMap<>();
        mqMap.put("userName",userName);
        mqMap.put("passWord",passWord);
        return mqMap;
    }



    @Override
    public ResponseEntity<Map> findPerson(PersonQueryDto personQueryDto) {
        String apiUrl = "/eags/api/pims/v1.0/query"
                +"?pageNum="+personQueryDto.getPageNum()
                +"&pageSize="+personQueryDto.getPageSize();
        if (!StringUtils.isEmpty(personQueryDto.getParam())){
            apiUrl=apiUrl+"&param="+personQueryDto.getParam();
        }
        if (!StringUtils.isEmpty(personQueryDto.getSearchCode())){
            apiUrl=apiUrl+"&searchCode="+personQueryDto.getSearchCode();
        }
        if (!StringUtils.isEmpty(personQueryDto.getRoleId())){
            apiUrl=apiUrl+"&roleId="+personQueryDto.getRoleId();
        }

        String httpMethod = "GET";
        argsUtil.restTemplateExchange(apiUrl,httpMethod,null);
        HttpHeaders headers = argsUtil.getHeaders();
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(null,headers );
        ResponseEntity<Map> responseEntity = restTemplate.exchange(argsUtil.getDaHuaConfig().getUrl()+apiUrl, HttpMethod.GET, formEntity, Map.class);
        return responseEntity;
    }

    @Override
    public Object findFaceRepository() {
        Integer pageNum=1;
        Integer pageSize=10;
        String param="";
        String apiUrl = "/eags/api/bfms/v1.0/repository/query"
                +"?pageNum="+pageNum
                +"&pageSize="+pageSize
                +"&param="+param;
        String httpMethod = "GET";
        argsUtil.restTemplateExchange(apiUrl,httpMethod,null);
        HttpHeaders headers = argsUtil.getHeaders();
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(null,headers );
        ResponseEntity<String> responseEntity = restTemplate.exchange(argsUtil.getDaHuaConfig().getUrl()+apiUrl, HttpMethod.GET, formEntity, String.class);
        return responseEntity;
    }

    @Override
    public Object findFaceRepositoryPerson() {
        Long repositoryId=1L;
        Integer pageNum=1;
        Integer pageSize=10;
        Integer stat=1;
        Integer roleId=1;
        String param="";
        String apiUrl = "/eags/api/bfms/v1.0/repository/person/query"
                +"?repositoryId="+repositoryId
                +"&pageNum="+pageNum
                +"&pageSize="+pageSize
                +"&stat="+stat
                +"&roleId="+roleId
                +"&param="+param;
        String httpMethod = "GET";
        argsUtil.restTemplateExchange(apiUrl,httpMethod,null);
        HttpHeaders headers = argsUtil.getHeaders();
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(null,headers );
        ResponseEntity<String> responseEntity = restTemplate.exchange(argsUtil.getDaHuaConfig().getUrl()+apiUrl, HttpMethod.GET, formEntity, String.class);
        return responseEntity;
    }

    /**
     * RSA公钥加密
     *
     * @param str
     *            加密字符串
     * @param publicKey
     *            公钥
     * @return 密文
     * @throws Exception
     *             加密过程中的异常信息
     */
    public static String encrypt( String str, String publicKey ) throws Exception{
        //base64编码的公钥
//        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey.getBytes()));
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes())));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));

    }

    /**
     * 解密
     * @param content
     * @param decodeKey
     * @return
     */
    public static String AesDecode(String content, String decodeKey) {
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance(EncryptType.AES.getType());
            //2.根据decodeKey规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(decodeKey.getBytes());
            keygen.init(128, secureRandom);
            //3.产生原始对称密钥
            SecretKey original_key = keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] raw = original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key = new SecretKeySpec(raw, EncryptType.AES.getType());
            //6.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance(EncryptType.AES_ECB_PKCS5.getType());
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //8.将加密并编码后的内容解码成字节数组
            byte[] byte_content = new BASE64Decoder().decodeBuffer(content);
            //9.解密
            byte[] byte_decode = cipher.doFinal(byte_content);
            String AES_decode = new String(byte_decode, StandardCharsets.UTF_8);
            return AES_decode;
        } catch (Exception e) {
            return content;
        }
    }

    /**
     * EncryptType 枚举类型
     */
    public enum EncryptType {
        MD5("MD5"),
        SSL("SSL"),
        TLS("TLS"),
        SHA512("SHA-512"),
        AES("AES"),
        AES_ECB_PKCS5("AES/ECB/PKCS5Padding");

        private String type;

        private EncryptType(String type) {
            this.type = type;
        }
        public String getType() {
            return this.type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }

}


